﻿using ORM.Base;
using ORM.Enum;
using ORM.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ORM.Util
{
    public class SQLBuilder
    {

        public string BuildCommonSQL<T>(T Entity,SQLType OperateType) where T : BaseEntity
        {
            Type tp = typeof(T);
            MapperEntity map = MapperBuilder.GetInstance().GetMap(tp);
            string tablename = map.TableName;
            string keyfieldname = map.KeyName;
            PropertyInfo[] infos = map.MapPropertyList;
            StringBuilder buildsql = new StringBuilder();
            switch (OperateType)
            {
                case SQLType.INSERT:
                    buildsql.AppendFormat("insert into {0}", tablename);
                    //字段
                    StringBuilder fieldsstr = new StringBuilder();
                    fieldsstr.Append(" (");
                    //值
                    StringBuilder valuestr = new StringBuilder();
                    valuestr.Append(" values (");
                    for (int i = 0; i < infos.Length; i++)
                    {
                        fieldsstr.AppendFormat(infos[i].Name);
                        valuestr.AppendFormat("@{0}", infos[i].Name);
                        if (i < infos.Length - 1)
                        {
                            fieldsstr.Append(",");
                            valuestr.Append(",");
                        }
                    }
                    fieldsstr.Append(" )");
                    valuestr.Append(" )");
                    buildsql.Append(fieldsstr.ToString()).Append(valuestr.ToString());
                    break;
                case SQLType.REMOVE:
                    buildsql.AppendFormat("delete from {0} where {1}=@{1}", tablename, keyfieldname);
                    break;
                case SQLType.SAVE:
                    buildsql.AppendFormat("update {0} set ", tablename);
                    StringBuilder bodysql = new StringBuilder();
                    if (infos.Length>0)
                    {
                        for (int i = 0; i < infos.Length; i++)
                        {
                            bodysql.AppendFormat("{0}=@{0}", infos[i].Name);
                            if (i < infos.Length - 1)
                            {
                                bodysql.Append(",");
                            }
                        }
                        buildsql.Append(bodysql.ToString());
                        buildsql.AppendFormat(" where {0}=@{0}", keyfieldname);
                    }
                    else
                    {
                        buildsql = new StringBuilder();
                    }
                    break;

            }
            return buildsql.ToString();
        }

        public string BuildSaveSQLForTrace<T>(T Entity) where T : BaseEntity
        {
            Type tp = typeof(T);
            MapperEntity map = MapperBuilder.GetInstance().GetMap(tp);
            string tablename = map.TableName;
            string keyfieldname = map.KeyName;
            PropertyInfo[] infos = map.MapPropertyList;
            StringBuilder buildsql = new StringBuilder();
            buildsql.AppendFormat("update {0} set ", tablename);
            StringBuilder bodysql = new StringBuilder();
            if (infos.Length > 0)
            {
                for (int i = 0; i < infos.Length; i++)
                {
                    bodysql.AppendFormat("{0}=@{0}", infos[i].Name);
                    if (i < infos.Length - 1)
                    {
                        bodysql.Append(",");
                    }
                }
                buildsql.Append(bodysql.ToString());
                buildsql.AppendFormat(" where {0}=@{0}", keyfieldname);
            }
            else
            {
                buildsql = new StringBuilder();
            }
            return buildsql.ToString();

        }

        public string BuildSaveSQLWithColumns<T>(T Enity, string[] SaveColumn) where T : BaseEntity
        {
            Type tp = typeof(T);
            MapperEntity map = MapperBuilder.GetInstance().GetMap(tp);
            string tablename = map.TableName;
            string keyfieldname = map.KeyName;
            StringBuilder buildsql = new StringBuilder();
            buildsql.AppendFormat("update {0} set ", tablename);
            for (int i = 0; i < SaveColumn.Count(); i++)
            {
                if (i != SaveColumn.Count() - 1)
                {
                    buildsql.AppendFormat("{0}=@{0},", SaveColumn[i]);
                }
                else
                {
                    buildsql.AppendFormat("{0}=@{0}", SaveColumn[i]);
                }
            }
            buildsql.AppendFormat(" where {0}=@{0}", keyfieldname);
            return buildsql.ToString();

        }

        public string BuildCountSQL<T>() where T : BaseEntity
        {
            Type tp = typeof(T);
            MapperEntity map = MapperBuilder.GetInstance().GetMap(tp);
            string tablename = map.TableName;
            return string.Format("select count(1) from {0}", tablename);
        }

        public string BuildFindOneSQL<T>() where T : BaseEntity
        {
            Type tp = typeof(T);
            MapperEntity map = MapperBuilder.GetInstance().GetMap(tp);
            string tablename = map.TableName;
            string keyfieldname = map.KeyName;
            return string.Format("select * from {0} where {1}=@{1}", tablename, keyfieldname);
        }

        public string BuildRecordSQL(Record record,SQLType OperateType)
        {
            StringBuilder buildsql = new StringBuilder();
            int all = record.RecordParams.Keys.Count;
            int count = 0;
            switch (OperateType)
            {
                case SQLType.INSERT:
                     buildsql.AppendFormat("insert into {0} ", record.TableName);
                    //字段
                    StringBuilder fieldsstr = new StringBuilder();
                    fieldsstr.Append(" (");
                    //值
                    StringBuilder valuestr = new StringBuilder();
                    valuestr.Append(" values (");

                    foreach (DictionaryEntry de in record.RecordParams)
                    {
                        fieldsstr.Append(de.Key);
                        valuestr.AppendFormat("@{0}", de.Key);
                        if (count < all - 1)
                        {
                            fieldsstr.Append(",");
                            valuestr.Append(",");
                        }
                        count++;
                    }
                    fieldsstr.Append(" )");
                    valuestr.Append(" )");
                    buildsql.Append(fieldsstr.ToString()).Append(valuestr.ToString());
                    break;
                case SQLType.REMOVE:
                    buildsql.AppendFormat("delete from {0} where {1}=@{1}", record.TableName, record.KeyFieldName);
                    break;
                case SQLType.SAVE:
                     buildsql.AppendFormat("update {0} set ", record.TableName);
                    StringBuilder bodysql = new StringBuilder();
                    foreach (DictionaryEntry de in record.RecordParams)
                    {
                        bodysql.AppendFormat("{0}=@{0}", de.Key);
                        if (count < all - 1)
                        {
                            bodysql.Append(",");
                        }
                        count++;
                    }
                    buildsql.Append(bodysql.ToString());
                    buildsql.AppendFormat(" where {0}=@{0}", record.KeyFieldName);
                    break;
                case SQLType.FINDONE:
                    buildsql.AppendFormat("select * from {0} where {1}=@{1}", record.TableName, record.KeyFieldName);
                    break;
                case SQLType.EXIST:
                    buildsql.AppendFormat("select count(1) from {0} where {1}=@{1}", record.TableName, record.KeyFieldName);
                    break;
            }
            return buildsql.ToString();
        }
    }
}
